package com.dingxin.ship_together_api.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dingxin.ship_together_api.common.utils.SaUtils;
import com.dingxin.ship_together_api.config.exception.CustomException;
import com.dingxin.ship_together_api.entity.*;
import com.dingxin.ship_together_api.entity.enums.ExceptionEnum;
import com.dingxin.ship_together_api.entity.enums.RouteTypeEnum;
import com.dingxin.ship_together_api.entity.vo.route.RouteAddVo;
import com.dingxin.ship_together_api.entity.vo.route.RouteDateVo;
import com.dingxin.ship_together_api.mapper.RouteSeatMapper;
import com.dingxin.ship_together_api.mapper.RouteSkuMapper;
import com.dingxin.ship_together_api.mapper.RouteSpuMapper;
import com.dingxin.ship_together_api.mapper.RouteTimeMapper;
import com.dingxin.ship_together_api.service.RouteDestinationService;
import com.dingxin.ship_together_api.service.RouteSkuService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
* Author: ctj
* Date: 2022-09-30
* Time: 17:14
*/

@Service
public class RouteSkuServiceImpl extends ServiceImpl<RouteSkuMapper, RouteSku> implements RouteSkuService{
    @Autowired
    private RouteSkuMapper routeSkuMapper;
    @Autowired
    private RouteSpuMapper routeSpuMapper;
    @Autowired
    private RouteDestinationService destinationService;
    @Autowired
    private RouteTimeMapper timeMapper;
    @Autowired
    private RouteSeatMapper seatMapper;
    @Autowired
    private SaUtils saUtils;

    // @Override
    // public PageUtils selectPage(PageQueryVo pageQueryVo){
    //     // 设置分页大小
    //     Page<RouteSku> page = new Page<>(pageQueryVo.getCurrPage(),pageQueryVo.getPageSize());
    //     // 构造分页查询条件
    //     QueryWrapper<RouteSku> queryWrapper = new QueryWrapper<>();
    //     // 分页查询
    //     Page<RouteSku> routeInfoPage = routeSkuMapper.selectPage(page, saUtils.generateQueryWrapper(queryWrapper,pageQueryVo));
    //     // 结果封装
    //     return new PageUtils(routeInfoPage);
    // }

    @Override public boolean logicDelete(RouteSku routeInfo) {
        routeInfo.setDeleted(true);
        return routeSkuMapper.updateById(routeInfo) > 0;
    }



    @Override public RouteTypeEnum getRouteType(Long skuId) {
        RouteSku routeSku = routeSkuMapper.selectById(skuId);
        Optional.ofNullable(routeSku).orElseThrow(() -> new CustomException(ExceptionEnum.ROUTE_NOT_FOUND));
        RouteSpu routeSpu = routeSpuMapper.selectById(routeSku.getRouteSpuId());
        Optional.ofNullable(routeSpu).orElseThrow(() -> new CustomException(ExceptionEnum.ROUTE_NOT_FOUND));
        return RouteTypeEnum.getEnumByCode(routeSpu.getRouteType());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override public boolean saveByRouteAddVo(RouteAddVo routeAddVo) {
        // 包船or拼船，执行不同逻辑
        // 拼船逻辑
        if (RouteTypeEnum.SPELL_SEATS.getCode().equals(routeAddVo.getRouteType())) {
            return spellSeatsRouteSave(routeAddVo);
        }
        // 包船逻辑
        if (RouteTypeEnum.All_SEATS.getCode().equals(routeAddVo.getRouteType())){
            return allSeatsRouteSave(routeAddVo);
        }
        return true;
    }

    @Override public List<RouteDateVo> dateList(String date) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        // 查询date日期后的30天内有航线的日期，如果有航线，附带该日期航线类型一并返回
        // 生成日期date后30天的日期列表
        ArrayList<Date> dateList = genDateList(DateUtil.parse(date),30);
        // // 查询date日期后的30天内有航线的日期
        dateList.parallelStream().forEach(tempDate->{
            List<RouteTime> routeTimes = timeMapper.selectList(new QueryWrapper<RouteTime>().between(RouteTime.COL_END_TIME, tempDate, DateUtil.offsetDay(tempDate, 1)).between(RouteTime.COL_START_TIME, tempDate, DateUtil.offsetDay(tempDate, 1)));
            if (routeTimes.size()>0) {
                List<Long> timeIds = routeTimes.stream().map(RouteTime::getId).collect(Collectors.toList());
                timeIds.forEach(timeId->{
                    List<RouteSku> skuList = routeSkuMapper.selectList(new QueryWrapper<RouteSku>().eq(RouteSku.COL_TIME_ID, timeId));
                    if (skuList.size()>0) {
                        map.put(DateUtil.format(tempDate, "yyyy-MM-dd"),skuList.get(0).getSeatId()==null?RouteTypeEnum.All_SEATS.getCode():RouteTypeEnum.SPELL_SEATS.getCode());
                    }
                });
            }
        });
        // 对map进行排序
        Map<String, Integer> sortedMap = map.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        ArrayList<RouteDateVo> routeDateVos = new ArrayList<>();
        sortedMap.forEach((k,v)->{
            RouteDateVo routeDateVo = new RouteDateVo();
            routeDateVo.setDate(k);
            routeDateVo.setRouteType(v);
            routeDateVos.add(routeDateVo);
        });
        return routeDateVos;
    }

    /**
     * 生成指定日期开始x天的日期列表
     * @param date
     * @return
     */
    private ArrayList<Date> genDateList(Date date,int days) {
        DateTime dateTime = DateUtil.date();
        dateTime.setHours(0);
        dateTime.setMinutes(0);
        dateTime.setSeconds(0);
        ArrayList<Date> dates = new ArrayList<>();
        dates.add(dateTime);
        // 循环获取30天的日期
        for (int i = 0; i < days-1; i++) {
            dateTime = DateUtil.offsetDay(dateTime, 1);
            dates.add(dateTime);
        }
        return dates;
    }

    /**
     * 包船航线新增逻辑
     * @param routeAddVo
     * @return
     */
    private boolean allSeatsRouteSave(RouteAddVo routeAddVo) {
        // 新增航线spu
        RouteSpu routeSpu = new RouteSpu();
        BeanUtils.copyProperties(routeAddVo,routeSpu);
        routeSpuMapper.insert(routeSpu);
        // 新增航线sku、注入id
        RouteSku routeSku = new RouteSku();
        BeanUtils.copyProperties(routeAddVo,routeSku);
        routeSku.setRouteSpuId(routeSpu.getId());
        // 新增时间
        RouteTime time = new RouteTime();
        time.setStartTime(routeAddVo.getStartTime());
        time.setEndTime(routeAddVo.getEndTime());
        timeMapper.insert(time);
        routeSku.setTimeId(time.getId());
        // 注入库存
        routeSku.setStock(1);
        // 新增目的地、注入id、价格
        List<RouteDestination> destinationList = routeAddVo.getDestinationList();
        destinationList.forEach(destination -> {
            routeSku.setAmount(destination.getAmount());
            destinationService.save(destination);
            routeSku.setDestinationId(destination.getId());
            RouteSku insertSku = new RouteSku();
            BeanUtils.copyProperties(routeSku,insertSku,RouteSku.COL_ID);
            routeSkuMapper.insert(insertSku);
        });
        return true;
    }

    /**
     * 拼船航线新增逻辑
     * @param routeAddVo
     * @return
     */
    public boolean spellSeatsRouteSave(RouteAddVo routeAddVo) {
        // 新增航线spu
        RouteSpu routeSpu = new RouteSpu();
        routeSpu.setSeats(routeAddVo.getSeatList().size());
        BeanUtils.copyProperties(routeAddVo,routeSpu);
        routeSpuMapper.insert(routeSpu);
        // 新增航线sku、注入id
        RouteSku routeSku = new RouteSku();
        BeanUtils.copyProperties(routeAddVo,routeSku);
        routeSku.setRouteSpuId(routeSpu.getId());
        // 新增目的地、注入id
        List<RouteDestination> destinationList = routeAddVo.getDestinationList();
        if (destinationList.size()>1) {
            throw new CustomException(ExceptionEnum.ROUTE_DESTINATION_MORE_THAN_ONE);
        }
        destinationService.saveBatch(destinationList);
        routeSku.setDestinationId(destinationList.get(0).getId());
        // 新增时间
        RouteTime time = new RouteTime();
        time.setStartTime(routeAddVo.getStartTime());
        time.setEndTime(routeAddVo.getEndTime());
        timeMapper.insert(time);
        routeSku.setTimeId(time.getId());
        // 注入库存
        routeSku.setStock(1);
        // 循环注入座位和价格
        List<RouteSeat> seatList = routeAddVo.getSeatList();
        seatList.forEach(seat->{
            seatMapper.insert(seat);
            routeSku.setSeatId(seat.getId());
            routeSku.setAmount(seat.getAmount());
            RouteSku insertSku = new RouteSku();
            BeanUtils.copyProperties(routeSku,insertSku,RouteSku.COL_ID);
            routeSkuMapper.insert(insertSku);
        });
        return true;
    }

}
